home *** CD-ROM | disk | FTP | other *** search
- Ok guys/gals, here it is. Basically, I'm going to show how I implemented a resource-only
- dll to hold bitmaps. Then I'll talk about how to retrieve them, get their color tables,
- and basically how to use them once their alive and living in your RAM. Um, also I'll talk
- about a technique I learned about from Mark Novisoff, founder of Microhelp in Georgia(you
- know Unistaller and all that), where you can store any files in one single file for a
- resource depository. The reason for this is two-fold 1) one of you asked about storing
- AVI's and WAV's instead of bmp's and 2) it's VB specific and the API ()'s to retrieve bmp's
- from true a dll can not store WAV's and AVI's.
-
- So, off we go:
- \ /
- :-)===00
- / \.
-
- PHASE I: Creating the DLL___________________________________________________________________
-
-
- This is the your source file.
- %%%%%%%%%%%%%%%%%MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //Resource only dll
- #include <windows.h>
-
- //Declare the Windows-callable WindowsExitProcedure()
- int FAR PASCAL _export WEP (int nParam);
-
- //This is the DLL's entry point, in the eye's of Windows
- int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg,
- WORD wHeapSize, LPSTR lpszCmdLine)
- {
- if (wHeapSize > 0)
- UnlockData(0); //This unlock's the dll's data segment
- //and is required
- return 1; //Then it returns 1 to Windows, saying all is well
- }
-
- //This is called by Windows when the dll's refernce count is = 0
- //or more simply when the dll is unloaded by you. If you want to
- //know about reference count's read about it in the SDK, it's somewhere
- //in there :)
- int FAR PASCAL _export WEP (int nParam)
- {
- return 1; //Just return 1 and Windows handles the rest
- }
- //Oh yea, get used to the reference count methodology, it is how
- //OLE manages the lifespan of an object too.
-
-
- Ok, this code gives you all you need for the main dll body code. It
- provided a way for Windows to say hello, do initialization if you need to, and then
- a way to say goodbye, do de-initialization if you need to.
- %%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-
- Then you need a module definition file. And here's the skeleton code for it.
- %%%%%%%%%%%%%%%%%%%%MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //Resource only DLL
- LIBRARY MODNAME //Name your module
- DESCRIPTION 'Put a description here for your module'
- EXETYPE WINDOWS
- CODE PRELOAD MOVEABLE DISCARDABLE
- DATA PRELOAD MOVEABLE SINGLE
- %%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-
- Ok, we've got the main dll body code done, the module's definition defined and now here's
- how to #include your bitmap's.
- %%%%%%%%%%%%%%%%%%%%MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- 1 BITMAP bitmap1.bmp //Or use a full path 'c:\\graphics\\bmps\\bitmap1.bmp'
- 2 BITMAP bitmap2.bmp
- %%%%%%%%%%%%%%%%%%%%End MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Now build your dll. That's it. You've given your Visual C compiler all the necessary info
- to turn your bitmaps into one resource file.
-
-
-
- PHASE II: Retrieving bitmaps in 256 colors from our DLL___________________________________
-
- Now you've got a dll to load into memory and extract image's from. The following is an
- excerpt from some C code I wrote to load an image from my dll.
-
- if ((hLib = LoadLibrary("dllres.dll")) < 32)
- {
- DestroyWindow(hwnd);
- return 0;
- }
-
- //Load DIBmp from dll
- hRes = FindResource(hLib, MAKEINTRESOURCE(2), RT_BITMAP);
- hGlobal = LoadResource(hLib, hRes);
- lpbmi = (LPBITMAPINFOHEADER)LockResource(hGlobal);
-
- //Create palette from dib
- hPal = CreateDIBPalette(lpbmi);
- hdc = GetDC(hwnd);
- SelectPalette(hdc, hPal, FALSE);
- RealizePalette(hdc);
-
- //check for non zero clrused member
- if (lpbmi->biClrUsed)
- iNumColors = (WORD)lpbmi->biClrUsed;
- else
- iNumColors = 256;
- hMyBmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbmi,
- (LONG)CBM_INIT,
- (LPSTR)lpbmi + lpbmi->biSize + iNumColors *
- sizeof(RGBQUAD),
- (LPBITMAPINFO)lpbmi,
- DIB_RGB_COLORS);
- ReleaseDC(hwnd, hdc);
- UnlockResource(hGlobal);
- FreeResource(hGlobal);
-
- Starting from the top, here we go. Basically, the only useful bitmaps these days are
- 8bit or 256 color bitmaps. So, the previous code compensates for this. It does this by
- getting a pointer to the bitmap data in memory. The FindRes, LoadRes and LockRes API calls
- are the sequence of calls that do this. In the FindRes, the RT_BITMAP parameter tells
- Windows were loading a bitmap from this dll, so it knows how to extract the bitmap. Now, we've
- got a pointer to bitmap in memory. We can then 'walk' to its color table to create a palette
- compatible with bitmap. Without, getting too far ahead of myself here's the code for creating
- this palette from my 8bit bitmap. It could be adjusted simply to compensate for 16 bit and 24
- bit bitmaps.
-
-
-
- HPALETTE CreateDIBPalette(LPBITMAPINFOHEADER lpbmi)
- {
- LPBITMAPINFO lpbi;
- LPLOGPALETTE lpPal;
- HANDLE hLogPal;
- HPALETTE hPal = NULL;
- int i, iColors;
-
- lpbi = (LPBITMAPINFO)lpbmi; //convert to struct that has color info
- if (lpbmi->biClrUsed) //check the # of colors used by your bmp's
- iColors = (WORD)lpbmi->biClrUsed;
- else
- iColors = 256;
-
-
- hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
- sizeof(PALETTEENTRY) * iColors);
- lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
- lpPal->palVersion = 0x300;
- lpPal->palNumEntries = iColors;
-
- for (i = 0; i < iColors; i++)
- {
- lpPal->palPalEntry[i].peRed = lpbi->bmiColors[i].rgbRed;
- lpPal->palPalEntry[i].peGreen = lpbi->bmiColors[i].rgbGreen;
- lpPal->palPalEntry[i].peBlue = lpbi->bmiColors[i].rgbBlue;
- lpPal->palPalEntry[i].peFlags = 0;
- }
- hPal = CreatePalette(lpPal);
- GlobalUnlock(hLogPal);
- GlobalFree(hLogPal);
-
- return hPal;
- }
-
-
- So, we get a long pointer to a bitmapinfoheader structure for our bitmap. I check the structure
- for the number of colors actually used by the bitmap. This isn't always 256 for an 8 bit bmp.
- It could be anything <= 256. Once I got that, I then allocate enough memory to hold a palette
- of this resolution in memory. I then GlobalLock it to get a pointer to this memory. Now, I can
- start initializing this memory. The lpPal->palVersion = hex 300 is required. Then, I read
- from the bitmap's structure, its color information into the logical palette. Once,
- I've filled the logical palette with color values I call CreatePalette to actually get a handle
- to the palette for future API calls. Then Unlock and Free the logical palette and return to
- the caller the handle to this particular DIB's palette.
-
-
- Now, if you look at the code from above we can then use this palette to set up a memDC in which
- we select this palette and then call CreateDIBitmap to actually create a ***device dependent
- bitmap****. Once you have a DDB, you then BitBlt to the screen or whatever you want.
-
-
- The bitmaps included in this zip file show how to create an indexed file to hold any type of
- information. In the example, the author shows how to fill the file with bitmaps, but you
- could put .AVI's or .WAV's in there.
-
- So, I hope all this was useful, I would have liked to put in a .hlp format but I just don't
- have the time. Anyway, I hope this helps. Sorry it took so darn long.
-
- Chris Douglass
- Imagesoft